package com.cy;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cy.config.EnumConst;
import com.cy.interceptor.EventLogInterceptor;
import com.cy.model.Account;
import com.cy.model.User;
import com.cy.shiro.QyUsernamePasswordToken;
import com.cy.shiro.ShiroUser;
import com.jfinal.core.Controller;
import com.jfinal.plugin.ehcache.CacheKit;
import com.jfinal.plugin.ehcache.IDataLoader;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.MDC;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BasicController extends Controller {

    protected static Logger logger;

    /**
     * 普通日志
     *
     * @param msg
     */
    protected void log(String msg) {
        getLog().trace(msg);
    }

    protected Logger getLog() {
        MDC.put("source", "backend");
        long startTime = Long.parseLong((String) MDC.get("_startTime"));
        MDC.put("costTime", System.currentTimeMillis() - startTime);

        Subject subject = SecurityUtils.getSubject();
        final ShiroUser shiroUser = (ShiroUser) subject.getPrincipal();
        if(null != shiroUser){
            if(shiroUser.getType() == 1){
                MDC.put("type", 0);
            }else if(shiroUser.getType() == 0){
                MDC.put("type", 1);
            }
        }
        return BasicController.logger;
    }

    public static void initLogger() {
        logger = LogManager.getLogger(EventLogInterceptor.EventLogName);
    }

    protected Map<String, Object> getRequestBody() {
        StringBuffer bodyBuffer = new StringBuffer();
        try {
            BufferedReader requestReader = getRequest().getReader();
            String str;
            while ((str = requestReader.readLine()) != null) {
                bodyBuffer.append(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return JSON.parseObject(bodyBuffer.toString());
    }


    protected Account getLoginAccount() {
        Subject subject = SecurityUtils.getSubject();
        final ShiroUser shiroUser = (ShiroUser) subject.getPrincipal();
        if (shiroUser == null || shiroUser.getType() != QyUsernamePasswordToken.Type.ACCOUNT.getCode()) {
            return null;
        }

        return (Account) shiroUser.getUser();
    }

    protected User getLoginUser() {
        Subject subject = SecurityUtils.getSubject();
        final ShiroUser shiroUser = (ShiroUser) subject.getPrincipal();
        if (shiroUser == null || shiroUser.getType() != QyUsernamePasswordToken.Type.USER.getCode()) {
            return null;
        }
        return CacheKit.get(User.dao.getCacheName(), shiroUser.getId(), new IDataLoader() {
            @Override
            public Object load() {
                return User.dao.findById(shiroUser.getId());
            }
        });

    }

    /**
     * 是否已登录
     * @param account 用户名
     * @param password 密码
     * @return 已登录用户(登录失败返回null)
     */
    protected User isLogined(String account, String password){
        User user = getLoginUser();
        if (user == null){
            Subject currentUser = SecurityUtils.getSubject();
            QyUsernamePasswordToken token = new QyUsernamePasswordToken(account, password,QyUsernamePasswordToken.Type.USER.getValue());
            try {
                currentUser.login(token);
                initLogger();
                getLog().info("login To :" + account + ",and success!");
            }catch (Exception e){
                return null;
            }
            user = getLoginUser();
        }
        return user;
    }

    protected String getCacheName() {
        return this.getClass().getName().toUpperCase() + "_CACHE";
    }

    public void renderSuccess(String... msg) {
        renderStatus(1, msg);
    }

    public void renderFail(String... msg) {
        renderStatus(0, msg);
    }

    public void renderNoPermission(String... msg) {
        renderStatus(EnumConst.RetCode.NO_PERMISSION.getCode(), msg);
    }

    protected void renderRetCode(EnumConst.RetCode code){
        renderStatus(code.getCode(), code.getValue());
    }

    protected void renderStatus(int status, String... msg) {
        renderStatus(status, null, msg);
    }

    protected void renderStatus(int status, Map<String, Object> param, String... msg) {
        JSONObject result;
        if (param != null) {
            result = new JSONObject(param);
        } else {
            result = new JSONObject();
        }
        result.put("msg", StringUtils.join(msg, "#"));
        result.put("status", status);
        renderJson(result);
    }

    public Map listToMap(List list) {
        Map<Object, Boolean> resultMap = new HashMap<>();
        for (Object obj : list) {
            if (null == obj) {
                continue;
            }
            resultMap.put(obj, true);
        }
        return resultMap;
    }

    /**
     * 获取真实IP
     * @return ip
     */
    protected String getIpAdress() {
        String ip = getRequest().getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
            ip = getRequest().getHeader("Proxy-Client-IP");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
            ip = getRequest().getHeader("WL-Proxy-Client-IP");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
            ip = getRequest().getRemoteAddr();
        return ip;
    }
}
